#include "logqueue.h"
#include <QDebug>

LogQueue::LogQueue(QObject *parent): QThread(parent){

}

void LogQueue::stopImmediately(){
    QMutexLocker<QMutex> locker(&m_lock);
    m_isCanRun = false;
}


void LogQueue::pushLog(Log *log){
    log_queue.push_msg(log);
}

void LogQueue::run(){
    qDebug() << "日志线程开始";
    m_isCanRun = true;
    for(;;){
        {
            QMutexLocker<QMutex> locker(&m_lock);
            if(m_isCanRun == false){
                fclose(logfile);
                return ;
            }
        }

        Log *log = log_queue.pop_msg();
        if(log == nullptr || log->ptr == nullptr){
            continue;
        }

        errno_t r = fopen_s(&logfile, R"(./log.txt)", "a");
        if(r != 0){
            qDebug() << "打开文件失败,错误码：" << r << "fwrite error: " << strerror(errno);
            continue;
        }
        qDebug() << "fopen_s success";

        qint64 hastowrite = log->len;
        qint64 ret = 0, haswrite = 0;
        int retryCount = 0;
        const int MAX_RETRIES = 10;

        while(haswrite < hastowrite){
            ret = fwrite((char *)log->ptr + haswrite, 1, hastowrite - haswrite, logfile);

            if(ret > 0){
                haswrite += ret;
            }else if(ret == 0){
                qDebug() << "fwrite returned 0 without error";
                break;
            }else{
                if(errno == EAGAIN || errno == EWOULDBLOCK){
                    if (retryCount++ >= MAX_RETRIES) {
                        qDebug() << "Reached maximum retries for EAGAIN/EWOULDBLOCK";
                        break;
                    }
                    msleep(1);
                    ret = 0;
                }else{
                    qDebug() << "fwrite error:" << strerror(errno);
                }
            }
        }

        if (haswrite < hastowrite) {
            qDebug() << "Failed to write entire log. Wrote" << haswrite << "bytes out of" << hastowrite;
        }

        if(log->ptr) free(log->ptr);
        if(log) free(log);

        fflush(logfile);
        fclose(logfile);
    }
}
